package com.itxh.mvc.servlet;

import com.itxh.factory.DefaultListableBeanFactory;
import com.itxh.model.BeanDefinition;
import com.itxh.mvc.adapter.HandlerAdapter;
import com.itxh.mvc.mapping.HandlerMapping;
import com.itxh.reader.XmlBeanDefinitionReader;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class DispatcherServlet extends AbstractHttpServlet{

    /*@Override
    protected void dispatch(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 查找处理器类
        String uri = req.getRequestURI();
        Object handler = null;
        if ("/query".equals(uri)){
            handler = new UserQueryHandler();
        }

        // 调用处理器类的处理方法
        if (handler instanceof HttpRequestHandler){
            ((HttpRequestHandler)handler).handleRequest(req,resp);
        }else if (handler instanceof SimpleController){
            ((SimpleController)handler).handleRequest(req,resp);
        }
        //处理结果
    }*/

    private List<HandlerMapping> handlerMappings = new ArrayList<>();
    private List<HandlerAdapter> handlerAdapters = new ArrayList<>();
    private DefaultListableBeanFactory beanFactory;
    @Override
    public void init(ServletConfig config) throws ServletException {
        String location = config.getInitParameter("contextConfigLocation");
        System.out.println(location);
        beanFactory = new DefaultListableBeanFactory();
        initBeanFactory(location);
        initStrategies();
        System.out.println(beanFactory.getBeanDefinitions());
        System.out.println(beanFactory);
    }

    private void initStrategies() {
        handlerMappings = beanFactory.getBeansByType(HandlerMapping.class);
        handlerAdapters = beanFactory.getBeansByType(HandlerAdapter.class);
        System.out.println(handlerMappings);
        System.out.println(handlerAdapters);
    }

    private void initBeanFactory(String location) {
        XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        xmlBeanDefinitionReader.loadBeanDefinitions(location);
        List<BeanDefinition> beanDefinitions = beanFactory.getBeanDefinitions();

        // 将工厂中的bean一次性创建出来
        for (BeanDefinition bd : beanDefinitions) {
            String name = bd.getId();
            beanFactory.getBean(name);
        }
    }

    @Override
    protected void dispatch(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        try {
            // 查找处理器类
            Object handler = getHandler(req);

            // 根据处理器获取合适的适配器
            HandlerAdapter ha = getHandlerAdapter(handler);
            if (ha == null){
                return;
            }
            // 调用请求处理方法
//        handleRequest(handler,req,resp);
            ha.handle(handler,req,resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private HandlerAdapter getHandlerAdapter(Object handler){
        if (handlerAdapters != null){
            for (HandlerAdapter ha : handlerAdapters) {
                if (ha.supports(handler)){
                    return ha;
                }
            }
        }
        return null;
    }

//    private HandlerAdapter getHandlerAdapter(Object handler, HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {
//        if (handler instanceof HttpRequestHandler){
//            ((HttpRequestHandler)handler).handleRequest(req,resp);
//        }else if (handler instanceof SimpleController){
//            ((SimpleController)handler).handleRequest(req,resp);
//        }

//    }

    private Object getHandler(HttpServletRequest req) {
//        String uri = req.getRequestURI();
//        Object handler = null;
//        if ("/query".equals(uri)){
////            handler = new UserQueryHandler();
//        }
//        return handler;

        if (handlerMappings != null){
            for (HandlerMapping hm : handlerMappings) {
                Object handler = hm.getHandler(req);
                if (handler != null){
                    return handler;
                }
            }
        }
        return null;
    }
}
